
import { staticPrefix } from '@/settings'

export const toString = Object.prototype.toString

export function Type(v) {
  return toString.call(v).replace(/\[object (.*)\]/, '$1')
}

export function isType(v, typeStr) {
  return Type(v).toLowerCase() === typeStr.toLowerCase()
}

export function isUndef(v) {
  return v === undefined || v === null
}

export function isDef(v) {
  return v !== undefined && v !== null
}

export function isEmpty(v) {
  return v === ''
}

export function deepCopy(v) {
  if (typeof v !== 'object') {
    return v
  }
  let copyV
  if (isType(v, 'Array')) {
    copyV = []
    for (let e of v) {
      e = deepCopy(e)
      copyV.push(e)
    }
  } else if (isType(v, 'Object')) {
    copyV = {}
    // eslint-disable-next-line prefer-const
    for (let [k, _v] of Object.entries(v)) {
      _v = deepCopy(_v)
      copyV[k] = _v
    }
  }
  return copyV
}

export function randomId() {
  return (Math.random() * 0xfffffff).toFixed().toString(16)
}

export function findItem(item, ...args) {
  for (const arg of args) {
    let hasItem = false
    for (const i of arg) {
      if (i === item) {
        hasItem = true
        break
      }
    }
    if (!hasItem) {
      return false
    }
  }
  return true
}

// 取交集
export function unite(...args) {
  if (args.length === 0) return args
  if (args.length === 1) return args[0]
  const uniteData = []
  for (let i = 0; i < args.length; i++) {
    const arg = args[i]
    const newArgs = [...args.slice(0, i), ...args.slice(i + 1)]
    for (const item of arg) {
      if (findItem(item, ...newArgs)) {
        uniteData.push(item)
      }
    }
  }
  return Array.from(new Set(uniteData))
}

/**
 * Parse the time to string
 * @param {(Object|string|number)} time
 * @param {string} cFormat
 * @returns {string}
 */
export function parseTime(time, cFormat) {
  if (arguments.length === 0) {
    return null
  }
  if (!time) return ''
  const format = cFormat || '{y}-{m}-{d} {h}:{i}:{s}'
  let date
  if (typeof time === 'object') {
    date = time
  } else {
    if ((typeof time === 'string')) {
      if (time.indexOf('T')) {
        time = time.replace('T', ' ')
      }
      if (time.indexOf('Z')) {
        time = time.replace('Z', ' ')
      }
      if (/^[0-9]+$/.test(time)) {
        time = parseInt(time)
      } else {
        time = time.replace(/-/g, '/') // 处理safari与ie兼容
      }
    }
    if ((typeof time === 'number') && (time.toString().length === 10)) {
      time = time * 1000
    }
    date = new Date(time)
  }
  const formatObj = {
    y: date.getFullYear(),
    m: date.getMonth() + 1,
    d: date.getDate(),
    h: date.getHours(),
    i: date.getMinutes(),
    s: date.getSeconds(),
    a: date.getDay()
  }
  const time_str = format.replace(/{(y|m|d|h|i|s|a)+}/g, (result, key) => {
    let value = formatObj[key]
    // Note: getDay() returns 0 on Sunday
    if (key === 'a') { return ['日', '一', '二', '三', '四', '五', '六'][value ] }
    if (result.length > 0 && value < 10) {
      value = '0' + value
    }
    return value || 0
  })
  return time_str
}

// url路径格式化
export function formatURL(url, prefix = staticPrefix) {
  if (!url || typeof url !== 'string') return ''
  if (!prefix) return url
  const Expression = /http(s)?:\/\/([\w-]+\.)+[\w-]+(\/[\w- .\/?%&=]*)?/
  const objExp = new RegExp(Expression)
  if (objExp.test(url)) {
    return url
  }
  if (url.indexOf('/') !== 0) {
    if (prefix.substr(-1) !== '/') {
      prefix = `${prefix}/`
    }
  } else {
    if (prefix.substr(-1) === '/') {
      prefix = prefix.substr(0, prefix.length - 1)
    }
  }
  return `${prefix}${url}`
}
// JSON对象转formData
export function json2FormData(params) {
  const formData = new FormData()
  Object.keys(params).forEach((key) => {
    formData.append(key, params[key])
  })
  return formData
}

// 获取keepAlive实例，清除cache的同时，destory掉当前实例（在需要清除的时候调用）
export const removeKeepAliveCacheForVueInstance = (vueInstance) => {
  const key =
    vueInstance.$vnode.key ??
    vueInstance.$vnode.componentOptions.Ctor.cid + (vueInstance.$vnode.componentOptions.tag ? `::${vueInstance.$vnode.componentOptions.tag}` : '')
  const cache = vueInstance.$vnode.parent.componentInstance.cache
  const keys = vueInstance.$vnode.parent.componentInstance.keys
  if (cache[key]) {
    vueInstance.$destroy()
    delete cache[key]
    const index = keys.indexOf(key)
    if (index > -1) {
      keys.splice(index, 1)
    }
  }
}

export default {
  install(Vue) {
    Object.defineProperty(Vue.prototype, '$Type', { value: Type })
    Object.defineProperty(Vue.prototype, '$isType', { value: isType })
    Object.defineProperty(Vue.prototype, '$isUndef', { value: isUndef })
    Object.defineProperty(Vue.prototype, '$isDef', { value: isDef })
    Object.defineProperty(Vue.prototype, '$isEmpty', { value: isEmpty })
    Object.defineProperty(Vue.prototype, '$deepCopy', { value: deepCopy })
    Object.defineProperty(Vue.prototype, '$parseTime', { value: parseTime })
    Object.defineProperty(Vue.prototype, '$formatURL', { value: formatURL })
    Object.defineProperty(Vue.prototype, '$removeKeepAliveCache', { value: removeKeepAliveCacheForVueInstance })
  }
}
